package practica1.ui.simulacion;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 *
 * @author Miguel González - Ceura
 */
public class PanelPintadoBacterias extends JPanel {
    
    private int bacteriasDia[][];
    private int comidaDia[][];
    private boolean zoom;
    private int xZoom;
    private int yZoom;
    private int xPosition;
    private int yPosition;
    private double escalaZoom;
    private boolean verComida;
    
    public PanelPintadoBacterias() {
        bacteriasDia = null;
        comidaDia = null;
        
        zoom = false;
        xZoom = 0;
        yZoom = 0;
        escalaZoom = 1.0;
        
        initListeners();
    }
    
    private void initListeners() {
        addMouseListener(new ZoomClick());
        addMouseWheelListener(new ZoomRueda());
    }
    
    public void pintarBacterias(int[][] bacteriasDia, int[][] comidaDia, boolean verComida) {
        this.verComida = verComida;
        
        this.bacteriasDia = new int[bacteriasDia.length][];
        for (int i = 0; i < bacteriasDia.length; i++) {
            this.bacteriasDia[i] = new int[bacteriasDia[i].length];
            System.arraycopy(bacteriasDia[i], 0, this.bacteriasDia[i],
                    0, bacteriasDia[i].length);
        }
        
        this.comidaDia = new int[comidaDia.length][];
        for (int i = 0; i < comidaDia.length; i++) {
            this.comidaDia[i] = new int[comidaDia[i].length];
            System.arraycopy(comidaDia[i], 0, this.comidaDia[i],
                    0, comidaDia[i].length);
        }
        
        repaint();
    }
    
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D graphics = (Graphics2D) g.create();
        
        //Pintamos el cuadrado
        int posX;
        int posY;
        int ladoCuadrado;
        //Sacamos las proporciones para pintarlo centrado
        if(getHeight() < getWidth()) {
            posY = 0;
            ladoCuadrado = getHeight();
            posX = (getWidth() - ladoCuadrado)>>1;
        } else {
            ladoCuadrado = getWidth();
            posX = 0;
            posY = (getHeight() - ladoCuadrado)>>1;
        }

        //Si se le pasan bacterias a pintar se pintan en el cuadrado
        if(bacteriasDia != null) {
            BufferedImage biPlato = new BufferedImage(bacteriasDia.length, bacteriasDia.length,
                BufferedImage.TYPE_INT_RGB);
            
            Graphics2D ggPlato = biPlato.createGraphics();
            
            if(zoom) {
                AffineTransform tx = AffineTransform.
                        getTranslateInstance(xZoom, yZoom);
                tx.scale(escalaZoom, escalaZoom);
                tx.translate(-xZoom, -yZoom);

                graphics.setTransform(tx);
            }
            
            for(int i=0; i<bacteriasDia.length; i++) {
                for(int j=0; j<bacteriasDia.length; j++) {
                    Color color;

                    int factorVisor;
                    int cantidad;
                    
                    if(!verComida) {
                        cantidad = bacteriasDia[i][j];
                        factorVisor = 1;
                    } else {
                        cantidad = comidaDia[i][j];
                        factorVisor = 4;
                    }
                    
                    if(cantidad >= 20 * factorVisor) {
                        color = new Color(166, 0, 0);
                    } else if(cantidad >= 15 * factorVisor &&
                            cantidad < 20 * factorVisor) {
                        color = Color.RED;
                    } else if(cantidad >= 10 * factorVisor && 
                            cantidad < 15 * factorVisor) {
                        color = Color.ORANGE;
                    } else if(cantidad >= 5 * factorVisor &&
                            cantidad < 10 * factorVisor) {
                        color = Color.YELLOW;
                    } else if(cantidad>= 1 * factorVisor &&
                            cantidad < 5 * factorVisor) {
                        color = Color.GREEN;
                    } else {
                        color = Color.WHITE;
                    }
                    
                    ggPlato.setColor(color);
                    ggPlato.fillRect(i, j, 1, 1);
                }
            }
            
            //Pintamos el buffered image del plato
            graphics.drawImage(biPlato, posX, posY,
                    ladoCuadrado, ladoCuadrado, this);
            
        } else {
            //Se muestra un mensaje de aviso
            String mensaje = "No hay simulación";
            Font fuente = new Font(Font.SANS_SERIF, Font.BOLD, 12);
            
            graphics.setColor(Color.WHITE);
            graphics.setFont(fuente);
            
            graphics.fillRect(posX, posY,
                            ladoCuadrado, ladoCuadrado);
            
            graphics.setColor(Color.BLACK);
            
            JLabel lblMensaje = new JLabel(mensaje);
            lblMensaje.setFont(fuente);
            int x = getWidth() / 2 - (int)lblMensaje.getPreferredSize().getWidth() / 2;
            int y = getHeight() / 2 - (int)lblMensaje.getPreferredSize().getHeight() / 2;
            graphics.drawString(mensaje, x, y);
        }
    }
    
    private class ZoomClick extends MouseAdapter {
        @Override
        public void mouseClicked(MouseEvent e) {
            if(zoom) {
                zoom = false;
                escalaZoom = 1.0;
                xZoom = 0;
                yZoom = 0;
                repaint();
            } else {
                xZoom = e.getX();
                yZoom = e.getY();
                zoom = true;
                escalaZoom = 4.0;
                repaint();
            }
        }
    }
    
    private class ZoomRueda implements MouseWheelListener {
        @Override
        public void mouseWheelMoved(MouseWheelEvent e) {
            if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
                escalaZoom -= (0.5 * e.getWheelRotation());
                
                if(escalaZoom < 1.0) {
                    escalaZoom = 1.0;
                    xZoom = 0;
                    yZoom = 0;
                    xPosition = 0;
                    yPosition = 0;
                    zoom = false;
                } else {
                    zoom = true;
                    if(xZoom == 0 && yZoom == 0) {
                        xZoom = xPosition = e.getX();
                        yZoom = yPosition = e.getY();
                    } else {
                        xZoom += (int)((e.getX() - xPosition) / escalaZoom);
                        yZoom += (int)((e.getY() - yPosition) / escalaZoom);
                        xPosition = e.getX();
                        yPosition = e.getY();
                    }
                    
                    repaint();
                }
            }
        }
    }
}
